<?php

namespace mybackend\controllers;

use Yii;
use common\error\ErrorCode;
use common\services\myhtsq\ContractService;
use common\services\myhtsq\ContractReceivableService;
use common\services\myhtsq\InvoiceService;
use common\services\myhtsq\ContractPaymentService;
use common\models\myhtsq\ContractReceivableModel;
use common\models\myhtsq\InvoiceModel;
use common\models\myhtsq\ContractPaymentModel;
use common\entities\myhtsq\ActionCode;
use yii\filters\AccessControl;
use common\repositories\myhtsq\ContractPaymentRepository;
use common\entities\myhtsq\MyscrmContractDistributionAmountEntity;

/**
 * Description of ReceivableController
 * 应收款控制器
 * @author chenxc
 */
class ReceivableController extends BaseController {

    private $_contractService;
    private $_contractReceivableService;
    private $_invoiceService;
    private $_contractPaymentService;

    public function __construct($id, $module, ContractService $contractService, ContractReceivableService $contractReceivableService, InvoiceService $invoiceService, ContractPaymentService $contractPaymentService, $config = array()) {
        $this->_contractService = $contractService;
        $this->_contractReceivableService = $contractReceivableService;
        $this->_invoiceService = $invoiceService;
        $this->_contractPaymentService = $contractPaymentService;
        parent::__construct($id, $module, $config);
    }

    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'rules' => [
                    [
                        'actions' => ['receivable-expired-remind'],
                        'allow' => true,
                    ],
                    [
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                ],
            ]
        ];
    }

    protected function roleAuthRules() {
        return [
            'actions' => ['ChangeReceivableDate', 'ChangeResponsiblePerson', 'DeleteContractPayment', 'DeleteContractReceivable',
                'DeleteInvoice', 'GetCanUseInvoiceInfo', 'GetContractPaymentHaveAmountByContract', 'GetContractReceivable',
                'GetContractUnifiedInfo', 'GetInvoiceReceivableInfoByContract', 'GetParentInvoiceInfo', 'MarkBadDebt',
                'MarkOperation', 'SaveContractPayment', 'SaveContractReceivable', 'SaveInvoiceReceivable', 'SplitContractReceivalble'],
            'rules' => [
                [
                    'allow' => true,
                    'actionCodeMaps' => [
                        'ChangeReceivableDate' => ActionCode::CONTRACT_MNG,
                        'ChangeResponsiblePerson' => ActionCode::CONTRACT_MNG,
                        'DeleteContractPayment' => ActionCode::PAYMENT_INFO_DEL,
                        'DeleteContractReceivable' => ActionCode::CONTRACT_MNG,
                        'DeleteInvoice' => ActionCode::INVOICE_MNG,
                        'GetCanUseInvoiceInfo' => ActionCode::INVOICE_MNG,
                        'GetContractPaymentHaveAmountByContract' => ActionCode::CONTRACT_VIEW,
                        'GetContractReceivable' => ActionCode::CONTRACT_VIEW,
                        'GetContractUnifiedInfo' => ActionCode::CONTRACT_VIEW,
                        'GetInvoiceReceivableInfoByContract' => ActionCode::INVOICE_VIEW,
                        'GetParentInvoiceInfo' => ActionCode::INVOICE_VIEW,
                        'MarkBadDebt' => ActionCode::CONTRACT_MNG,
                        'MarkOperation' => ActionCode::CONTRACT_MNG,
                        'SaveContractPayment' => ActionCode::PAYMENT_INFO_ADD,
                        'SaveContractReceivable' => ActionCode::CONTRACT_MNG,
                        'SaveInvoiceReceivable' => ActionCode::INVOICE_MNG,
                        'SplitContractReceivalble' => ActionCode::CONTRACT_MNG,
                    ],
                ],
//                [
//                    'allow' => true,
//                    'actionCodeMaps' => [
//                        'DeleteContractPayment' => ActionCode::PAYMENT_INFO_MOD,
//                        'SaveContractPayment' => ActionCode::PAYMENT_INFO_ADD,
//
//                    ],
//                ]
            ]
        ];
    }

    /**
     * 获取合同的统一信息（不受权限控制）
     */
    public function actionGetContractUnifiedInfoWithoutAuth()
    {
        $this->makeContractUnifiedInfo();
    }

    /**
     * 获取合同的统一信息
     */
    public function actionGetContractUnifiedInfo()
    {
        $this->makeContractUnifiedInfo();
    }

    private function makeContractUnifiedInfo()
    {
        $signAmount = $rentAmount = $deliveryAmount = $billingAmount = $paymentAmount = 0;
        $contractId = $this->getParam('contractId');
        // 合同信息
        $contract = $this->_contractService->getContractInfo($contractId);
        if (isset($contract) && isset($contract['contract'])) {
            $signAmount = $contract['contract']['sign_amount'];
            $rentAmount = $contract['contract']['rent_amount'];
            $deliveryAmount = $contract['contract']['delivery_amount'];
        }
        // 应收款项信息
        $receivables = $this->_contractReceivableService->getReceivableInfoByContractId($contractId);

        if (isset($receivables) && count($receivables) > 0) {
            foreach ($receivables as $v) {
                $billingAmount += floatval($v['billing_amount']);
                $paymentAmount += floatval($v['received_amount']);
            }
        }
        // 发票信息
        $invoices = $this->_invoiceService->getInvoiceListByContractId($contractId);
        // 回款信息
        $payments = $this->_contractPaymentService->getPaymentInfoByContractId($contractId);

        $summary = array(
            'signAmount' => $signAmount,
            'rentAmount' => $rentAmount,
            'deliveryAmount' => $deliveryAmount,
            'billingAmount' => $billingAmount,
            'paymentAmount' => $paymentAmount
        );

        $result = array(
            'summary' => $summary,
            'receivables' => $receivables,
            'invoices' => $invoices,
            'payments' => $payments
        );

        $this->exportJson($result);
    }

    /**
     * 根据合同ID获取对应的应收款信息
     */
    public function actionGetContractReceivable() {
        $contractId = $this->getParam('contractId');
        $receivables = $this->_contractReceivableService->getReceivableInfoByContractId($contractId, false);
        $this->exportJson($receivables, $this->_contractReceivableService->getErrCode(), $this->_contractReceivableService->getErrMsg());
    }

    /**
     * 保存合同应收款项信息
     */
    public function actionSaveContractReceivable() {
        $this->exitIfNotPost();
        $contractReceivableModel = new ContractReceivableModel(['scenario' => 'savecontractreceivable']);
        if ($contractReceivableModel->load(Yii::$app->request->post(), '')) {
            $result = $this->_contractReceivableService->saveContractReceivable($contractReceivableModel);
            $this->exportJson($result, $this->_contractReceivableService->getErrCode(), $this->_contractReceivableService->getErrMsg());
        } else {
            $this->errorParam();
        }
    }

    /**
     * 删除合同应收款信息
     */
    public function actionDeleteContractReceivable() {
        $receivableId = $this->getParam('receivable_id', 'post');
        $result = $this->_contractReceivableService->deleteContractReceivable($receivableId);
        $this->exportJson($result, $this->_contractReceivableService->getErrCode(), $this->_contractReceivableService->getErrMsg());
    }

    /**
     * 保存合同应收款拆分信息
     */
    public function actionSplitContractReceivalble() {
        $this->exitIfNotPost();
        $contractReceivableModel = new ContractReceivableModel(['scenario' => 'splitontractreceivable']);
        if ($contractReceivableModel->load(Yii::$app->request->post(), '')) {
            $result = $this->_contractReceivableService->splitContractReceivable($contractReceivableModel);
            $this->exportJson($result, $this->_contractReceivableService->getErrCode(), $this->_contractReceivableService->getErrMsg());
        } else {
            $this->errorParam();
        }
    }

    /**
     * 保存合同应收款项责任人变更信息
     */
    public function actionChangeResponsiblePerson() {
        $this->exitIfNotPost();
        $contractReceivableModel = new ContractReceivableModel(['scenario' => 'changeresponsibleperson']);
        if ($contractReceivableModel->load(Yii::$app->request->post(), '')) {
            $result = $this->_contractReceivableService->changeResponsiblePerson($contractReceivableModel);
            $this->exportJson($result, $this->_contractReceivableService->getErrCode(), $this->_contractReceivableService->getErrMsg());
        } else {
            $this->errorParam();
        }
    }

    /**
     * 保存合同应收款项名称变更信息
     */
    public function actionChangeResponsibleItem(){
        $this->exitIfNotPost();
        $contractReceivableModel = new ContractReceivableModel(['scenario' => 'changeresponsibleitem']);
        if ($contractReceivableModel->load(Yii::$app->request->post(), '')) {
            $result = $this->_contractReceivableService->changeResponsibleItem($contractReceivableModel);
            $this->exportJson($result, $this->_contractReceivableService->getErrCode(), $this->_contractReceivableService->getErrMsg());
        } else {
            $this->errorParam();
        }
    }

    /**
     * 保存合同应收关联收入项变更信息
     */
    public function actionChangeResponsibleRevenueType(){
        $this->exitIfNotPost();
        $contractReceivableModel = new ContractReceivableModel(['scenario' => 'changereceivablerevenuetype']);
        if ($contractReceivableModel->load(Yii::$app->request->post(), '')) {
            $result = $this->_contractReceivableService->changeResponsibleRevenueType($contractReceivableModel);
            $this->exportJson($result, $this->_contractReceivableService->getErrCode(), $this->_contractReceivableService->getErrMsg());
        } else {
            $this->errorParam();
        }
    }

    /**
     * 保存合同应收款项应收款项变更信息
     */
    public function actionChangeReceivableDate() {
        $this->exitIfNotPost();
        $contractReceivableModel = new ContractReceivableModel(['scenario' => 'changeresponsibleperson']);
        if ($contractReceivableModel->load(Yii::$app->request->post(), '')) {
            $result = $this->_contractReceivableService->changeReceivableDate($contractReceivableModel);
            $this->exportJson($result, $this->_contractReceivableService->getErrCode(), $this->_contractReceivableService->getErrMsg());
        } else {
            $this->errorParam();
        }
    }

    /**
     * 标记为坏账
     */
    public function actionMarkBadDebt() {
        $receivableId = $this->getParam('receivable_id', 'post');
        $isBadDebt = $this->getParam('is_bad_debt', 'post');
        $badDebtReason = $this->getParam('bad_debt_reason', 'post');
        $result = $this->_contractReceivableService->markBadDebt($receivableId, $isBadDebt, $badDebtReason);
        $this->exportJson($result, $this->_contractReceivableService->getErrCode(), $this->_contractReceivableService->getErrMsg());
    }

    /**
     * 标记为运营关注
     */
    public function actionMarkOperation() {
        $receivableId = $this->getParam('receivable_id', 'post');
        $isOperation = $this->getParam('is_operation', 'post');
        $result = $this->_contractReceivableService->markOperation($receivableId, $isOperation);
        $this->exportJson($result, $this->_contractReceivableService->getErrCode(), $this->_contractReceivableService->getErrMsg());
    }

    /**
     * 保存发票信息（与应收款的关系）
     */
    public function actionSaveInvoiceReceivable() {
        $this->exitIfNotPost();
        $invoiceModel = new InvoiceModel(['scenario' => 'saveinvoice']);
        $invoiceModel->is_import = 2;       // 2：合同系统新增发票
        if ($invoiceModel->load(Yii::$app->request->post(), '')) {

            //如果引入的是红冲发票，则需要判断已开票金额够不够减
            $checkResult = $this->_contractReceivableService->checkRedInvoiceAmount($invoiceModel);
            if($checkResult === false){
                $this->exportJson($checkResult, $this->_contractReceivableService->getErrCode(), $this->_contractReceivableService->getErrMsg());
            }

            $result = $this->_contractReceivableService->saveInvoiceReceivable($invoiceModel);
            $this->exportJson($result, $this->_contractReceivableService->getErrCode(), $this->_contractReceivableService->getErrMsg());
        } else {
            $this->errorParam();
        }
    }

    /**
     *  获取可以作为父级发票的发票信息
     */
    public function actionGetParentInvoiceInfo() {
        $keyword = $this->getParam('keyword');
        $result = $this->_invoiceService->getParentInvoiceInfo($keyword);
        $this->exportJson($result);
    }

    /**
     * 获取未关联的发票
     */
    public function actionGetCanUseInvoiceInfo() {
        $contractId = $this->getParam('contractId');
        $keyword = $this->getParam('keyword');
        $result = $this->_invoiceService->getCanUseInvoiceInfo($contractId, $keyword);
        $this->exportJson($result, $this->_contractReceivableService->getErrCode(), $this->_contractReceivableService->getErrMsg());
    }

    /**
     * 删除发票信息
     */
    public function actionDeleteInvoice() {
        $invoiceId = $this->getParam('invoice_id', 'post');
        $result = $this->_invoiceService->deleteInvoice($invoiceId, true);
        $this->exportJson($result, $this->_invoiceService->getErrCode(), $this->_invoiceService->getErrMsg());
    }

    /**
     * 根据合同id获取对应的 发票与应收款对应关系 记录
     */
    public function actionGetInvoiceReceivableInfoByContract() {
        $contractId = $this->getParam('contractId');
        $result = $this->_contractReceivableService->getInvoiceReceivableInfoByContractId($contractId);
        $this->exportJson($result, $this->_contractReceivableService->getErrCode(), $this->_contractReceivableService->getErrMsg());
    }

    /**
     * 保存合同回款信息
     */
    public function actionSaveContractPayment() {
        $this->exitIfNotPost();
        $contractPaymentModel = new ContractPaymentModel(['scenario' => 'savecontractpayment']);
        if ($contractPaymentModel->load(Yii::$app->request->post(), '')) {

            $contractId =  $this->getParam('contract_id','post');
            $this->getParam('invoicePayments','post');
            $achievementData = $this->_contractService->getAuthorizationAchievementByContractId($contractId);//新业绩表

            $SummaryAchievement = 0;
            foreach ($achievementData as $item){
                $SummaryAchievement+=(int)$item['settlement_average_amount'];
            }

            $result = $this->_contractPaymentService->saveContractPayment($contractPaymentModel,$contractId);//回款入库

            if(!empty($result)){
                $this->_contractService->achievementGrouping($contractId);
                $sumPayment = ContractPaymentRepository::getPaymentSumByContractId($contractId);

                $entity = new MyscrmContractDistributionAmountEntity();
                $editAchievement = $entity::find()->where(['contract_id'=>$contractId])->all();

                $SummaryAchievement = 0;
                foreach ($editAchievement as $item){
                    $SummaryAchievement+=(int)$item['settlement_average_amount'];
                }

                foreach ($editAchievement as $item){
                    $item->receivable_average_amount = round($sumPayment)*$item->settlement_average_amount/$SummaryAchievement;
                    //修复坏味道
                    $item->save();
                }
            }


            $this->exportJson($result, $this->_contractPaymentService->getErrCode(), $this->_contractPaymentService->getErrMsg());
        } else {
            $this->errorParam();
        }
    }

    /**
     * 获取单条回款信息
     */
    public function actionGetContractPayment()
    {
        $paymentId = $this->getParam('payment_id');
        $data = $this->_contractPaymentService->getContractPayment($paymentId);
        $this->exportJson($data, $this->_contractPaymentService->getErrCode(), $this->_contractPaymentService->getErrMsg());
    }

    /**
     * 编辑回款（绑定发票）
     */
    public function actionBindContractPaymentToInvoice()
    {
        $this->exitIfNotPost();
        $contractPaymentModel = new ContractPaymentModel(['scenario' => 'savecontractpayment']);
        if ($contractPaymentModel->load(Yii::$app->request->post(), '')) {
            $result = $this->_contractPaymentService->bindContractPaymentToInvoice($contractPaymentModel);
            $this->exportJson($result, $this->_contractPaymentService->getErrCode(), $this->_contractPaymentService->getErrMsg());
        } else {
            $this->errorParam();
        }
    }

    /**
     * 删除回款信息
     */
    public function actionDeleteContractPayment() {
        $paymentId = $this->getParam('payment_id', 'post');
        $result = $this->_contractPaymentService->deleteContractPayment($paymentId);
        $this->exportJson($result, $this->_contractPaymentService->getErrCode(), $this->_contractPaymentService->getErrMsg());
    }

    /**
     * 获取发票绑定的回款列表
     */
    public function actionGetPaymentListByInvoiceId()
    {
        $invoiceId = $this->getParam('invoice_id', 'get', '');
        $result = $this->_contractPaymentService->getContractPaymentInfoByInvoiceId($invoiceId);
        $this->exportJson($result, $this->_contractPaymentService->getErrCode(), $this->_contractPaymentService->getErrMsg());
    }

    /**
     * 解除回款与发票的关联关系
     */
    public function actionUnBindPaymentForInvoice()
    {
        $paymentIds = $this->getParam('payment_ids', 'post', []);//要取消绑定的paymentId集合
        $result = $this->_contractPaymentService->unBindPaymentForInvoice($paymentIds);
        $this->exportJson($result, $this->_contractPaymentService->getErrCode(), $this->_contractPaymentService->getErrMsg());
    }

    /**
     * 获取还未完全开完发票的回款记录
     */
    public function actionGetContractPaymentHaveAmountByContract() {
        $contractId = $this->getParam('contractId');
        $result = $this->_contractPaymentService->getContractPaymentHaveAmountByContract($contractId);
        $this->exportJson($result, $this->_contractPaymentService->getErrCode(), $this->_contractPaymentService->getErrMsg());
    }

    /*发送邮件提醒*/
    /**
     * 应收时间到期前7天提醒
     */
    public function actionReceivableExpiredRemind(){
        $this->_contractReceivableService->receivableExpiredRemind();
    }
    
    /**
     * 根据发票id获取发票信息
     */
    public function actionGetInvoiceInfoById () {
        $invoiceId = $this->getParam('invoiceId');
        $result = $this->_invoiceService->getInvoiceInfoById($invoiceId);
        $this->exportJson($result, $this->_contractPaymentService->getErrCode(), $this->_contractPaymentService->getErrMsg());
    }

    /**
     * 获取合同应收款信息(供项目授权单独使用)
     * @param $contractManageId
     */
    public function actionGetReceivable($contractManageId){
        if(empty($contractManageId)){
            $this->exportJson([],-1,"参数缺失");
        }
        // 应收款项信息
        $receivables = $this->_contractReceivableService->getReceivableInfoByContractId($contractManageId);
        $this->exportJson($receivables, $this->_contractPaymentService->getErrCode(), $this->_contractPaymentService->getErrMsg());
    }
}
